package com.indoornavi.verbal.graph;

import java.util.ArrayList;
import java.util.Iterator;


public class Path {
	private ArrayList<Pair> pairs;
	private int totalWeight;
	private boolean visited;
	//private boolean hasWeight;
	
	public Path(){
		pairs = new ArrayList<Pair>();
		totalWeight=Integer.MAX_VALUE;
		visited=false;
	}
	
	public Path(Pair pair){
		pairs = new ArrayList<Pair>();
		totalWeight=Integer.MAX_VALUE;
		addPair(pair);
		visited = false;
	}
	
	/**
	 * Returns if the path has elements.
	 * @return true - if the path has elements.
	 * false - if the path has no elements.
	 */
	public boolean hasSize(){
		return !pairs.isEmpty();
	}
	
	/**
	 * Returns the total weight for the path.
	 * Must call ({@link hasSize} beforehand. If no size, weight will be 0.
	 * @return
	 */
	public int getTotalWeight(){
		return totalWeight;
	}
	
	public void addPair(Pair p){
		if(pairs.size()==0){
//			System.out.println("Weight reset");
			totalWeight=0;
		}
		pairs.add(p);
//		if(p.getWeight()>10 || p.getWeight()<0){
//			System.out.println("ERROR: WEIGHT IS ODD!");
//		}
		totalWeight = totalWeight+p.getWeight();
	}
	
	public void addPairs(ArrayList<Pair> pairList){
		Iterator<Pair> pairIterator = pairList.iterator();
		while(pairIterator.hasNext()){
			addPair(pairIterator.next());
		}
	}
	
	/**
	 * Get the last element in the path
	 * @return
	 */
	public Pair getDestination(){
		return pairs.get(pairs.size()-1);
	}
	
	/**
	 * a deep copy of the path, returned as a new Path object
	 * @return
	 */
	public Path duplication(){
		Path p2 = new Path();
		//p2.addPairs((ArrayList<Pair>)pairs.clone());
		p2.addPairs(pairs);
		return p2;
	}
	
	
	
	public ArrayList<Pair> getPairs() {
		return pairs;
	}
	
	

	public static void main (String [] args){
		Graph G = new Graph("graph.dat");
		Path path = new Path(G.getFromMatrix(0, 1));
		System.out.println("Inserted: "+ G.getFromMatrix(0, 1).getName());
		path.addPair(G.getFromMatrix(1, 0));
		System.out.println("Inserted: "+ G.getFromMatrix(1, 0).getName());
		System.out.println(path.hasSize());
		System.out.println("max_value: "+Integer.MAX_VALUE);
		System.out.println(path.getTotalWeight());
		System.out.println(path.getDestination().getName());
		System.out.println("path weight: "+ path.getTotalWeight());
		Path duplicated = path.duplication();
		System.out.println("duplicated weight: "+duplicated.getTotalWeight());
		
		
	}

	public boolean isVisited() {
		return visited;
	}

	public void setVisited(boolean visited) {
		this.visited = visited;
	}
	
	public void setTotalWeight(int weight){
		totalWeight = weight;
	}
	
	public ArrayList<Edge> getEdgesWithIntermediary(){
		ArrayList<Edge> edgeList = new ArrayList<Edge>();
		edgeList.add(pairs.get(0).getEdge(0));
		Iterator<Pair> pairsIterator = pairs.iterator();
		Pair tempPair = null;
		ArrayList<Edge> elist =null;
		while(pairsIterator.hasNext()){
			tempPair = pairsIterator.next();
			elist = tempPair.getIntermediateEdges();
			if(!elist.isEmpty()){
					edgeList.addAll(elist);
			}
			edgeList.add(tempPair.getEdge(1));
		}
		return edgeList;
	}
	
	public ArrayList<Edge> getEdges(){
		ArrayList<Edge> edgeList = new ArrayList<Edge>();
		edgeList.add(pairs.get(0).getEdge(0));
		Iterator<Pair> pairsIterator = pairs.iterator();
		while(pairsIterator.hasNext()){
			edgeList.add(pairsIterator.next().getEdge(1));
		}
		return edgeList;
	}
	
	public ArrayList<Vertex> getVertices(){
		ArrayList<Vertex> vList = new ArrayList<Vertex>();
		ArrayList<Edge> eList = getEdgesWithIntermediary();
		Iterator<Edge> eIter = eList.iterator();
		Edge eCurr = null;
		Edge eNext = null;
		Vertex vPrev = null;
		Vertex vCurr = null;
		Vertex vNext = null;
		eCurr=eIter.next();//all paths should have this, or there is no path.
		eNext=eIter.next();//all paths should have this, or there is no path.
		vCurr = getCommonVertex(eCurr, eNext);
		vPrev = getOtherVertex(eCurr, vCurr);
		vNext = getOtherVertex(eNext, vCurr);
		vList.add(vPrev);
		vList.add(vCurr);
		vList.add(vNext);
		while(eIter.hasNext()){
			//eCurr = eNext;
			vCurr = vNext;
			eNext = eIter.next();
			vNext = getOtherVertex(eNext, vCurr);
			vList.add(vNext);
		}
		
		return vList;
		
	}
	
	private Vertex getCommonVertex(Edge e1, Edge e2){
		String e1_0 = e1.getVertices()[0].getName();
		String e1_1 = e1.getVertices()[1].getName();
		String e2_0 = e2.getVertices()[0].getName();
		String e2_1 = e2.getVertices()[1].getName();
		
		if(e1_0.equals(e2_0) || e1_0.equals(e2_1)){
		 return e1.getVertices()[0];
		}
		else if(e1_1.equals(e2_0) || e1_1.equals(e2_1)){
			return e1.getVertices()[1];
		}
		else{
			return null;
		}
	}
	
	private Vertex getOtherVertex(Edge e, Vertex v){
		//assumes that provided vertex is part of edge, else it will fail.
		if(v.getName().equals(e.getVertices()[0].getName())){
			return e.getVertices()[1];
		}
		else{
			return e.getVertices()[0];
		}
	}
	
	
}
